let sdl_init () =
  begin
    Sdl.init [`EVERYTHING];
    Sdlevent.enable_events Sdlevent.all_events_mask;
  end

let get_dims img =
  ((Sdlvideo.surface_info img).Sdlvideo.w, (Sdlvideo.surface_info
  img).Sdlvideo.h)

(**)
let list_of_point = ref []

let point_to_tab x y z =
  let file = open_out_gen [Open_append;Open_creat]0o777 "coord.obj" in
    begin
      output_string file ("v " ^ string_of_int(x) ^ " " ^ string_of_int(y) ^ " " ^
			    string_of_int(z) ^ "\n");
      close_out file;
      list_of_point := (x, y, z) :: !(list_of_point)
    end



let color_to_altitude color =
  match color with
    | c when c = (0, 0, 255) -> 0
    | c when c = (0, 63, 0) -> 10
    | c when c = (0, 127, 0) -> 20
    | c when c = (0, 191, 0) -> 30
    | c when c = (0, 255, 0) -> 40
    | c when c = (0, 255, 127) -> 50
    | _ -> 60

let get_altitude x y =
  let origin_img = Sdlloader.load_image Sys.argv.(1) in
    color_to_altitude (Sdlvideo.get_pixel_color origin_img x y)


(*maillage *)
let maillage img frequency =
 let (width, height) = get_dims img in
   for y = 0 to (height - 1) do
     for x = 0 to (width - 1) do
       (* horizontal and vertical lines *)
       if(y mod frequency = 0)||(x mod frequency = 0)then
	 begin
	   if ((Sdlvideo.get_pixel_color img x y) = (0,0,0)) then
	     (* FIXME A CHANGER LA HAUTEUR SUIVANT LA COULEUR*) 
	     point_to_tab x y (get_altitude x y);
	   Sdlvideo.put_pixel_color img x y (0,0,0);
	 end;
       (* diagonal lines *)
       if x mod frequency = y mod frequency  then
         Sdlvideo.put_pixel_color img x y (0,0,0);
       (* color the intersections of the lines *)
       if x mod frequency = 0 && y mod frequency = 0 then
	 begin
	   (* put x y and z in a list *)
	   (* FIXME A CHANGER LA HAUTEUR SUIVANT LA COULEUR*) point_to_tab x y (get_altitude x y);
	   Sdlvideo.put_pixel_color img x y (255,255,55);
	 end
     done;
   done;
  (* line at the bottom of the picture *)
   for x = 0 to width - 1 do
     Sdlvideo.put_pixel_color img x (height-1) (0,0,0)
   done;
   (* color the intersection at the bottom of the picture *)
   for x = 0 to (width / frequency)  do
     Sdlvideo.put_pixel_color img (x*frequency) (height-1) (255,255,55)
   done;
   (* line on the right of the picture *)
   for y = 0 to height do
     Sdlvideo.put_pixel_color img (width-1) y (0,0,0)
   done;
   (* color the intersection on the right of the picture *)
   for y =0 to (height/frequency)  do
     Sdlvideo.put_pixel_color img (width-1) (y*frequency) (255,255,55)
done




let comprgb (r1,g1,b1) (r2,g2,b2) =
  ((r1 = r2)&&(g1 = g2)&&(b1 = b2))||((r2 = 0)&&(g2 = 0)&&(b2 = 0))
    (* View if two color qre the same*)

let comp_two_color (r1, g1, b1) (r2, g2, b2) =
  ((r1 = r2) && (g1 = g2) && (b1 = b2))

let rec colorexist color = function
  | [] -> false
  | e::l -> (comp_two_color e color) || (colorexist color l)

let countcolor image l nb=
  let (w, h) = get_dims(image) in
  let currentcolor = ref (0, 0, 0) in
    for i = 0 to (w - 1) do
      for j = 0 to (h - 1) do
	currentcolor := (Sdlvideo.get_pixel_color image i j);
	if (not(colorexist  (!currentcolor)(!l) )) then
	  begin
	    nb := (!nb) + 1;
	    l := (!currentcolor) :: (!l);
	  end
      done
    done


  let parse_uptodown img =
    let (width, height) = get_dims img in
    for x = 0 to (width - 2) do
      for y = 0 to (height - 2) do
	if not (comprgb (Sdlvideo.get_pixel_color img x y)
		  (Sdlvideo.get_pixel_color img x (y+1))) then
	  Sdlvideo.put_pixel_color img x y (0, 0, 0)
      done
    done

let parse_lefttoright img =
  let (width, height) = get_dims img in
    for y = 0 to (height - 2) do
      for x = 0 to (width - 2) do
	if not (comprgb (Sdlvideo.get_pixel_color img x y)
		  (Sdlvideo.get_pixel_color img (x + 1)y)) then
	  Sdlvideo.put_pixel_color img x y (0, 0, 0)
      done
    done

let element_to_string color=
  let (r, g, b) = color in
    ( "(" ^ (string_of_int(r)) ^ ", " ^ (string_of_int(g)) ^ ", " ^
  (string_of_int(b)) ^ ")")

let rec aux_write file = function
  |[] -> ""
  |e::l -> (element_to_string e) ^ "\n" ^ (aux_write file l)

let rec aux_append_file_list file list i s =
  if !i > 0 then
    begin
      i := !i - 1;
      s := !s ^ "\n" ^ (input_line file);
      match list with
	| [] -> ()
	| e::l -> s := !s ^ (string_of_int e);
	    aux_append_file_list file l i s
    end


let string_write filename s =
  let file = open_out_gen [Open_trunc; Open_append]0o777 filename in
    begin
      output_string file s;
      close_out file;
    end

let append_file_list filename list =
  let s = ref "" in
  let i = ref 0 in
  let file = open_in filename in
    begin
      s := !s ^ (input_line file);
      i := int_of_string (!s);
      aux_append_file_list file list i s;
      close_in file;
      string_write filename !s;
    end


let write image file_name =
  let l = ref [] in
  let nb = ref 0 in
    countcolor image l nb ;
    let file = open_out_gen [Open_append;Open_creat]0o777 file_name in
      if (!l = []) then
	begin
	  output_string file "Echec" ;
	end
      else
	begin
	  output_string file (string_of_int(!nb) ^"\n" ^ aux_write file (!l));
	  close_out file;
	end

let show img dst =
  let d = Sdlvideo.display_format img in
    Sdlvideo.blit_surface d dst ();
    Sdlvideo.flip dst

let rec wait_key () =
  let e = Sdlevent.wait_event () in
    match e with
    Sdlevent.KEYDOWN _ -> ()
      | _ -> wait_key ()


let main () =
  begin
    (* Initialisation de SDL *)
    sdl_init ();
    (* Chargement d'une image *)
    let img = Sdlloader.load_image "carte2.bmp"  in
      (* On récupère les dimensions *)
    let (w,h) = get_dims img in
      (* On crée la surface d'affichage en doublebuffering *)
    let display = Sdlvideo.set_video_mode w h [`DOUBLEBUF] in
      (* on affiche l'image *)
      write img "result.txt";
      parse_uptodown img;
      parse_lefttoright img;
      maillage img 20;
      Sdlvideo.save_BMP img "result.bmp";
      show img display;
      append_file_list "result.txt" [10; 20; 30; 40; 50; 60; 70];
      
      wait_key ();
      exit 0
  end

let _ = main()
